/*
 * FaceCat图形通讯框架
 * 著作权编号:2015SR229355+2020SR0266727
 * 上海卷卷猫信息技术有限公司
 */

using System;
using System.Collections.Generic;
namespace FaceCat {
    /// <summary>
    /// 单元格样式
    /// </summary>
    public class FCGridCellStyle {
        public FCHorizontalAlign m_align = FCHorizontalAlign.Inherit;

        /// <summary>
        /// 获取内容的横向排列样式
        /// </summary>
        public virtual FCHorizontalAlign getAlign() {
            return m_align;
        }

        /// <summary>
        /// 设置内容的横向排列样式
        /// </summary>
        public virtual void setAlign(FCHorizontalAlign value) {
            m_align = value;
        }

        public bool m_autoEllipsis;

        /// <summary>
        /// 获取是否在文字超出范围时在结尾显示省略号
        /// </summary>
        public virtual bool autoEllipsis() {
            return m_autoEllipsis;
        }

        /// <summary>
        /// 设置是否在文字超出范围时在结尾显示省略号
        /// </summary>
        public virtual void setAutoEllipsis(bool value) {
            m_autoEllipsis = value;
        }

        public long m_backColor = FCColor.None;

        /// <summary>
        /// 获取背景色
        /// </summary>
        public virtual long getBackColor() {
            return m_backColor;
        }

        /// <summary>
        /// 设置背景色
        /// </summary>
        public virtual void setBackColor(long value) {
            m_backColor = value;
        }

        public FCFont m_font;

        /// <summary>
        /// 获取字体
        /// </summary>
        public virtual FCFont getFont() {
            return m_font;
        }

        /// <summary>
        /// 设置字体
        /// </summary>
        public virtual void setFont(FCFont value) {
            m_font = value;
        }

        public long m_textColor = FCColor.None;

        /// <summary>
        /// 获取文字颜色
        /// </summary>
        public virtual long getTextColor() {
            return m_textColor;
        }

        /// <summary>
        /// 设置文字颜色
        /// </summary>
        public virtual void setTextColor(long value) {
            m_textColor = value;
        }
    }

    /// <summary>
    /// 单元格
    /// </summary>
    public class FCGridCell : FCAttribute {
        /// <summary>
        /// 创建单元格
        /// </summary>
        public FCGridCell() {
        }


        /// <summary>
        /// 析构函数
        /// </summary>
        ~FCGridCell() {
            delete();
        }

        public bool m_allowEdit;

        /// <summary>
        /// 获取是否可编辑
        /// </summary>
        public virtual bool allowEdit() {
            return m_allowEdit;
        }

        /// <summary>
        /// 设置是否可编辑
        /// </summary>
        public virtual void setAllowEdit(bool value) {
            m_allowEdit = value;
        }

        public int m_colSpan = 1;

        /// <summary>
        /// 获取跨越的列数
        /// </summary>
        public virtual int getColSpan() {
            return m_colSpan;
        }

        /// <summary>
        /// 设置跨越的列数
        /// </summary>
        public virtual void setColSpan(int value) {
            m_colSpan = value;
        }

        public FCGridColumn m_column;

        /// <summary>
        /// 获取所在列
        /// </summary>
        public virtual FCGridColumn getColumn() {
            return m_column;
        }

        /// <summary>
        /// 设置所在列
        /// </summary>
        public virtual void setColumn(FCGridColumn value) {
            m_column = value;
        }

        public FCGrid m_grid;

        /// <summary>
        /// 获取表格
        /// </summary>
        public virtual FCGrid getGrid() {
            return m_grid;
        }

        /// <summary>
        /// 设置表格
        /// </summary>
        public virtual void setGrid(FCGrid value) {
            m_grid = value;
        }

        public bool m_isDeleted;

        /// <summary>
        /// 获取或设置是否已被销毁
        /// </summary>
        public virtual bool isDeleted() {
            return m_isDeleted; 
        }

        public String m_name;

        /// <summary>
        /// 获取名称
        /// </summary>
        public virtual String getName() {
            return m_name;
        }

        /// <summary>
        /// 设置名称
        /// </summary>
        public virtual void setName(String value) {
            m_name = value;
        }

        public FCGridRow m_row;

        /// <summary>
        /// 获取所在行
        /// </summary>
        public virtual FCGridRow getRow() {
            return m_row;
        }

        /// <summary>
        /// 设置所在行
        /// </summary>
        public virtual void setRow(FCGridRow value) {
            m_row = value;
        }

        public int m_rowSpan = 1;

        /// <summary>
        /// 获取跨越的行数
        /// </summary>
        public virtual int getRowSpan() {
            return m_rowSpan;
        }

        /// <summary>
        /// 设置跨越的行数
        /// </summary>
        public virtual void setRowSpan(int value) {
            m_rowSpan = value;
        }

        public FCGridCellStyle m_style;

        /// <summary>
        /// 获取样式
        /// </summary>
        public virtual FCGridCellStyle getStyle() {
            return m_style;
        }

        /// <summary>
        /// 设置样式
        /// </summary>
        public virtual void setStyle(FCGridCellStyle value) {
            m_style = value;
        }

        public Object m_tag = null;

        /// <summary>
        /// 获取TAG值
        /// </summary>
        public virtual Object getTag() {
            return m_tag;
        }

        /// <summary>
        /// 设置TAG值
        /// </summary>
        public virtual void setTag(Object value) {
            m_tag = value;
        }

        /// <summary>
        /// 获取文字
        /// </summary>
        public virtual String getText() {
            return getString();
        }

        /// <summary>
        /// 设置文字
        /// </summary>
        public virtual void setText(String value) {
            setString(value);
        }

        /// <summary>
        /// 调用方法
        /// </summary>
        /// <param name="funcName">名称</param>
        /// <param name="parameters">参数</param>
        /// <returns></returns>
        public virtual String callFunction(String funcName, String parameters)
        {
            return "";
        }

        /// <summary>
        /// 单元格大小比较，用于排序
        /// </summary>
        /// <param name="cell">比较单元格</param>
        /// <returns>1:较大 0:相等 -1:较小</returns>
        public virtual int compareTo(FCGridCell cell) {
            return 0;
        }

        /// <summary>
        /// 销毁资源
        /// </summary>
        public virtual void delete() {
            m_isDeleted = true;
        }

        /// <summary>
        /// 获取布尔型数值
        /// </summary>
        /// <returns>布尔型数值</returns>
        public virtual bool getBool() {
            return false;
        }

        /// <summary>
        /// 获取双精度浮点值
        /// </summary>
        /// <returns>双精度浮点值</returns>
        public virtual double getDouble() {
            return 0;
        }

        /// <summary>
        /// 获取单精度浮点值
        /// </summary>
        /// <returns>单精度浮点值</returns>
        public virtual float getFloat() {
            return 0;
        }

        /// <summary>
        /// 获取整型数值
        /// </summary>
        /// <returns>整型数值</returns>
        public virtual int getInt() {
            return 0;
        }

        /// <summary>
        /// 获取长整型数值
        /// </summary>
        /// <returns>长整型数值</returns>
        public virtual long getLong() {
            return 0;
        }

        /// <summary>
        /// 获取要绘制的文字
        /// </summary>
        /// <returns>要绘制的文字</returns>
        public virtual String getPaintText() {
            return getText();
        }

        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <param name="name">属性名称</param>
        /// <param name="value">返回属性值</param>
        /// <param name="type">返回属性类型</param>
        public virtual void getAttribute(String name, ref String value, ref String type) {
            switch (name)
            {
                case "align":
                    {
                        type = "enum:FCHorizontalAlign";
                        FCGridCellStyle style = getStyle();
                        if (style != null)
                        {
                            value = FCTran.horizontalAlignToStr(style.getAlign());
                        }
                        break;
                    }
                case "allowedit":
                    type = "bool";
                    value = FCTran.boolToStr(allowEdit());
                    break;
                case "autoellipsis":
                    {
                        type = "bool";
                        FCGridCellStyle style = getStyle();
                        if (style != null)
                        {
                            value = FCTran.boolToStr(style.autoEllipsis());
                        }
                        break;
                    }
                case "backcolor":
                    {
                        type = "color";
                        FCGridCellStyle style = getStyle();
                        if (style != null)
                        {
                            value = FCTran.colorToStr(style.getBackColor());
                        }
                        break;
                    }
                case "colspan":
                    type = "int";
                    value = FCTran.intToStr(getColSpan());
                    break;
                case "font":
                    {
                        type = "font";
                        FCGridCellStyle style = getStyle();
                        if (style != null && style.getFont() != null)
                        {
                            value = FCTran.fontToStr(style.getFont());
                        }
                        break;
                    }
                case "textcolor":
                    {
                        type = "color";
                        FCGridCellStyle style = getStyle();
                        if (style != null)
                        {
                            value = FCTran.colorToStr(style.getTextColor());
                        }
                        break;
                    }
                case "name":
                    type = "text";
                    value = getName();
                    break;
                case "rowspan":
                    type = "int";
                    value = FCTran.intToStr(getRowSpan());
                    break;
                case "text":
                    type = "text";
                    value = getText();
                    break;
                default:
                    type = "undefined";
                    value = "";
                    break;
            }
        }

        /// <summary>
        /// 获取属性名称列表
        /// </summary>
        /// <returns></returns>
        public virtual ArrayList<String> getAttributeNames() {
            ArrayList<String> attributeNames = new ArrayList<String>();
            attributeNames.AddRange(new String[] { "Align", "AllowEdit", "AutoEllipsis", "BackColor", "ColSpan", "Font", "Name", "RowSpan", "Text", "TextColor"});
            return attributeNames;
        }

        /// <summary>
        /// 获取字符型数值
        /// </summary>
        /// <returns>字符型数值</returns>
        public virtual String getString() {
            return "";
        }

        /// <summary>
        /// 添加单元格方法
        /// </summary>
        public virtual void onAdd() {
        }

        /// <summary>
        /// 重绘方法
        /// </summary>
        /// <param name="paint">绘图对象</param>
        /// <param name="rect">矩形</param>
        /// <param name="clipRect">裁剪矩形</param>
        /// <param name="isAlternate">是否交替行</param>
        public virtual void onPaint(FCPaint paint, FCRect rect, FCRect clipRect, bool isAlternate) {
            int clipW = clipRect.right - clipRect.left;
            int clipH = clipRect.bottom - clipRect.top;
            if (clipW > 0 && clipH > 0) {
                if (m_grid != null && m_row != null && m_column != null) {
                    //判断选中
                    String text = getPaintText();
                    bool selected = false;
                    if (m_grid.getSelectionMode() == FCGridSelectionMode.SelectCell) {
                        ArrayList<FCGridCell> selectedCells = m_grid.getSelectedCells();
                        int selectedCellSize = selectedCells.size();
                        for (int i = 0; i < selectedCellSize; i++) {
                            if (selectedCells.get(i) == this) {
                                selected = true;
                                break;
                            }
                        }
                    } else if (m_grid.getSelectionMode() == FCGridSelectionMode.SelectFullColumn) {
                        ArrayList<FCGridColumn> selectedColumns = m_grid.getSelectedColumns();
                        int selectedColumnsSize = selectedColumns.size();
                        for (int i = 0; i < selectedColumnsSize; i++) {
                            if (selectedColumns.get(i) == m_column) {
                                selected = true;
                                break;
                            }
                        }
                    } else if (m_grid.getSelectionMode() == FCGridSelectionMode.SelectFullRow) {
                        ArrayList<FCGridRow> selectedRows = m_grid.getSelectedRows();
                        int selectedRowsSize = selectedRows.size();
                        for (int i = 0; i < selectedRowsSize; i++) {
                            if (selectedRows.get(i) == m_row) {
                                selected = true;
                                break;
                            }
                        }
                    }

                    //获取颜色
                    FCFont font = null;
                    long backColor = FCColor.None;
                    long textColor = FCColor.None;
                    bool autoEllipsis = m_grid.autoEllipsis();
                    FCGridRowStyle rowStyle = m_grid.getRowStyle();
                    if (isAlternate) {
                        FCGridRowStyle alternateRowStyle = m_grid.getAlternateRowStyle();
                        if (alternateRowStyle != null) {
                            rowStyle = alternateRowStyle;
                        }
                    }
                    if (rowStyle != null) {
                        if (m_grid.getSelectionMode() != FCGridSelectionMode.SelectFullRow) {
                            if (backColor == FCColor.None) {
                                if (selected) {
                                    backColor = rowStyle.getSelectedBackColor();
                                } else if (m_row == m_grid.getHoveredRow()) {
                                    backColor = rowStyle.getHoveredBackColor();
                                } else {
                                    backColor = rowStyle.getBackColor();
                                }
                            }
                        }
                        if (font == null) {
                            font = rowStyle.getFont();
                        }
                        if (textColor == FCColor.None) {
                            if (selected) {
                                textColor = rowStyle.getSelectedTextColor();
                            } else if (m_row == m_grid.getHoveredRow()) {
                                textColor = rowStyle.getHoveredTextColor();
                            } else {
                                textColor = rowStyle.getTextColor();
                            }
                        }
                    }

                    FCHorizontalAlign horizontalAlign = m_column.getCellAlign();
                    if (m_style != null) {
                        if (m_style.autoEllipsis()) {
                            autoEllipsis = m_style.autoEllipsis();
                        }
                        if (m_style.getBackColor() != FCColor.None) {
                            backColor = m_style.getBackColor();
                        }
                        if (m_style.getFont() != null) {
                            font = m_style.getFont();
                        }
                        if (m_style.getTextColor() != FCColor.None) {
                            textColor = m_style.getTextColor();
                        }
                        if (m_style.getAlign() != FCHorizontalAlign.Inherit) {
                            horizontalAlign = m_style.getAlign();
                        }
                    }
                    paint.fillRect(backColor, rect);
                    FCSize tSize = paint.textSize(text, font, -1);
                    FCPoint tPoint = new FCPoint(rect.left + 1, rect.top + clipH / 2 - tSize.cy / 2);
                    int width = rect.right - rect.left;
                    if (tSize.cx < width) {
                        if (horizontalAlign == FCHorizontalAlign.Center) {
                            tPoint.x = rect.left + (rect.right - rect.left - tSize.cx) / 2;
                        }
                        else if (horizontalAlign == FCHorizontalAlign.Right) {
                            tPoint.x = rect.right - tSize.cx - 2;
                        }
                    }
                    FCRect tRect = new FCRect(tPoint.x, tPoint.y, tPoint.x + tSize.cx, tPoint.y + tSize.cy);
                    if (autoEllipsis && (tRect.right > clipRect.right || tRect.bottom > clipRect.bottom)) {
                        if (tRect.right > clipRect.right) {
                            tRect.right = clipRect.right;
                        }
                        if (tRect.bottom > clipRect.bottom) {
                            tRect.bottom = clipRect.bottom;
                        }
                        paint.drawTextAutoEllipsis(text, textColor, font, tRect);
                    }
                    else {
                        paint.drawText(text, textColor, font, tRect, -1);
                    }
                }
            }
        }

        /// <summary>
        /// 移除单元格方法
        /// </summary>
        public virtual void onRemove() {
        }

        /// <summary>
        /// 缩放
        /// </summary>
        /// <param name="scaleFactorX">横向比例</param>
        /// <param name="scaleFactorY">纵向比例</param>
        public virtual void onScaling(double scaleFactorX, double scaleFactorY) {
            if (m_style != null) {
                if (m_style.m_font != null) {
                    m_style.m_font.m_fontSize = (float)(m_style.m_font.m_fontSize * (scaleFactorX + scaleFactorY) / 2);
                }
            }
        }

        /// <summary>
        /// 设置布尔型数值
        /// </summary>
        /// <param name="value">数值</param>
        public virtual void setBool(bool value) {
        }

        /// <summary>
        /// 设置双精度浮点值
        /// </summary>
        /// <param name="value">数值</param>
        public virtual void setDouble(double value) {
        }

        /// <summary>
        /// 设置单精度浮点值
        /// </summary>
        /// <param name="value">数值</param>
        public virtual void setFloat(float value) {
        }

        /// <summary>
        /// 设置整型数值
        /// </summary>
        /// <param name="value">数值</param>
        public virtual void setInt(int value) {
        }

        /// <summary>
        /// 设置长整型数值
        /// </summary>
        /// <param name="value">数值</param>
        public virtual void setLong(long value) {
        }

        /// <summary>
        /// 设置属性
        /// </summary>
        /// <param name="name">属性名称</param>
        /// <param name="value">属性值</param>
        public virtual void setAttribute(String name, String value)
        {
            switch (name)
            {
                case "align":
                    {
                        if (m_style == null)
                        {
                            m_style = new FCGridCellStyle();
                        }
                        m_style.setAlign(FCTran.strToHorizontalAlign(value));
                        break;
                    }
                case "allowedit":
                    setAllowEdit(FCTran.strToBool(value));
                    break;
                case "autoellipsis":
                    {
                        if (m_style == null)
                        {
                            m_style = new FCGridCellStyle();
                        }
                        m_style.setAutoEllipsis(FCTran.strToBool(value));
                        break;
                    }
                case "backcolor":
                    {
                        if (m_style == null)
                        {
                            m_style = new FCGridCellStyle();
                        }
                        m_style.setBackColor(FCTran.strToColor(value));
                        break;
                    }
                case "colspan":
                    setColSpan(FCTran.strToInt(value));
                    break;
                case "font":
                    {
                        if (m_style == null)
                        {
                            m_style = new FCGridCellStyle();
                        }
                        m_style.setFont(FCTran.strToFont(value));
                        break;
                    }
                case "textcolor":
                    {
                        if (m_style == null)
                        {
                            m_style = new FCGridCellStyle();
                        }
                        m_style.setTextColor(FCTran.strToColor(value));
                        break;
                    }
                case "name":
                    setName(value);
                    break;
                case "rowspan":
                    setRowSpan(FCTran.strToInt(value));
                    break;
                case "text":
                    setText(value);
                    break;
            }
        }

        /// <summary>
        /// 设置字符型数值
        /// </summary>
        /// <param name="value">数值</param>
        public virtual void setString(String value) {
        }
    }

    /// <summary>
    /// 视图单元格
    /// </summary>
    public class FCGridViewCell : FCGridCell, FCTouchEventCallBack {
        /// <summary>
        /// 创建单元格
        /// </summary>
        public FCGridViewCell() {
        }

        /// <summary>
        /// 析构函数
        /// </summary>
        ~FCGridViewCell() {
            if (m_view != null) {
                m_view.delete();
                m_view = null;
            }
        }

        public FCView m_view;

        /// <summary>
        /// 获取视图
        /// </summary>
        public virtual FCView getView() {
            return m_view;
        }

        /// <summary>
        /// 设置视图
        /// </summary>
        public virtual void setView(FCView value) {
            m_view = value;
        }

        /// <summary>
        /// 获取要绘制的文字
        /// </summary>
        /// <returns>要绘制的文字</returns>
        public override String getPaintText() {
            return "";
        }

        /// <summary>
        /// 获取字符型数值
        /// </summary>
        /// <returns>字符型数值</returns>
        public override String getString() {
            if (m_view != null) {
                return m_view.getText();
            }
            else {
                return "";
            }
        }

        /// <summary>
        /// 触摸事件
        /// </summary>
        /// <param name="eventName"></param>
        /// <param name="sender"></param>
        /// <param name="touchInfo"></param>
        /// <param name="invoke"></param>
        public void callTouchEvent(String eventName, Object sender, FCTouchInfo touchInfo, Object invoke) {
            if (sender == m_view) {
                if (eventName == "ontouchdown") {
                    onViewTouchDown(touchInfo.clone());
                } else if (eventName == "ontouchmove") {
                    onViewTouchMove(touchInfo.clone());
                } else if (eventName == "ontouchup") {
                    onViewTouchUp(touchInfo.clone());
                } else if (eventName == "ontouchwheel") {
                    onViewTouchWheel(touchInfo.clone());
                }
            }
        }

        /// <summary>
        /// 添加单元格方法
        /// </summary>
        public override void onAdd() {
            FCGrid grid = getGrid();
            if (m_view != null && grid != null) {
                grid.addView(m_view);
                m_view.addEvent(this, "ontouchdown", null);
                m_view.addEvent(this, "ontouchmove", null);
                m_view.addEvent(this, "ontouchup", null);
                m_view.addEvent(this, "ontouchwheel", null);
            }
        }

        /// <summary>
        /// 视图触摸按下方法
        /// </summary>
        /// <param name="touchInfo">触摸信息</param>
        public virtual void onViewTouchDown(FCTouchInfo touchInfo) {
            FCGrid grid = getGrid();
            if (m_view != null && grid != null) {
                FCTouchInfo newTouchInfo = touchInfo.clone();
                newTouchInfo.m_firstPoint = grid.pointToView(m_view.pointToNative(touchInfo.m_firstPoint));
                newTouchInfo.m_secondPoint = grid.pointToView(m_view.pointToNative(touchInfo.m_secondPoint));
                grid.onTouchDown(newTouchInfo);
            }
        }

        /// <summary>
        /// 视图触摸移动方法
        /// </summary>
        /// <param name="touchInfo">触摸信息</param>
        public virtual void onViewTouchMove(FCTouchInfo touchInfo) {
            FCGrid grid = getGrid();
            if (m_view != null && grid != null) {
                FCTouchInfo newTouchInfo = touchInfo.clone();
                newTouchInfo.m_firstPoint = grid.pointToView(m_view.pointToNative(touchInfo.m_firstPoint));
                newTouchInfo.m_secondPoint = grid.pointToView(m_view.pointToNative(touchInfo.m_secondPoint));
                grid.onTouchMove(newTouchInfo);
            }
        }

        /// <summary>
        /// 视图触摸抬起方法
        /// </summary>
        /// <param name="touchInfo">触摸信息</param>
        public virtual void onViewTouchUp(FCTouchInfo touchInfo) {
            FCGrid grid = getGrid();
            if (m_view != null && grid != null) {
                FCTouchInfo newTouchInfo = touchInfo.clone();
                newTouchInfo.m_firstPoint = grid.pointToView(m_view.pointToNative(touchInfo.m_firstPoint));
                newTouchInfo.m_secondPoint = grid.pointToView(m_view.pointToNative(touchInfo.m_secondPoint));
                grid.onTouchUp(newTouchInfo);
            }
        }

        /// <summary>
        /// 视图触摸滚轮滚动方法
        /// </summary>
        /// <param name="touchInfo">触摸信息</param>
        public virtual void onViewTouchWheel(FCTouchInfo touchInfo) {
            FCGrid grid = getGrid();
            if (m_view != null && grid != null) {
                FCTouchInfo newTouchInfo = touchInfo.clone();
                newTouchInfo.m_firstPoint = grid.pointToView(m_view.pointToNative(touchInfo.m_firstPoint));
                newTouchInfo.m_secondPoint = grid.pointToView(m_view.pointToNative(touchInfo.m_secondPoint));
                grid.onTouchWheel(newTouchInfo);
            }
        }

        /// <summary>
        /// 重绘方法
        /// </summary>
        /// <param name="paint">绘图对象</param>
        /// <param name="rect">矩形</param>
        /// <param name="clipRect">裁剪矩形</param>
        /// <param name="isAlternate">是否交替行</param>
        public override void onPaint(FCPaint paint, FCRect rect, FCRect clipRect, bool isAlternate) {
            base.onPaint(paint, rect, clipRect, isAlternate);
            onPaintView(paint, rect, clipRect);
        }

        /// <summary>
        /// 重绘方法
        /// </summary>
        /// <param name="paint">绘图对象</param>
        /// <param name="rect">矩形</param>
        /// <param name="clipRect">裁剪矩形</param>
        public virtual void onPaintView(FCPaint paint, FCRect rect, FCRect clipRect) {
            if (m_view != null) {
                FCRect bounds = new FCRect(rect.left + 1, rect.top + 1, rect.right - 1, rect.bottom - 1);
                m_view.setBounds(bounds);
                clipRect.left -= rect.left;
                clipRect.top -= rect.top;
                clipRect.right -= rect.left;
                clipRect.bottom -= rect.top;
                m_view.setRegion(clipRect);
            }
        }

        /// <summary>
        /// 移除单元格方法
        /// </summary>
        public override void onRemove() {
            FCGrid grid = getGrid();
            if (m_view != null && grid != null) {
                m_view.removeEvent(this, "ontouchdown");
                m_view.removeEvent(this, "ontouchmove");
                m_view.removeEvent(this, "ontouchup");
                m_view.removeEvent(this, "ontouchwheel");
                grid.removeView(m_view);
            }
        }

        /// <summary>
        /// 设置字符型数值
        /// </summary>
        /// <param name="value">数值</param>
        public override void setString(String value) {
            if (m_view != null) {
                m_view.setText(value);
            }
        }
    }
}
